<template>
<!-- 模型第15层 -->
    <div>
        <dv-loading v-if="loading">Loading...</dv-loading>
        <div id="container" ref="container">    
        </div>
        <div class="floor-labels" ref="floorLabel">
            <!-- <router-link to="/Floor_15" style="font-size:0.2rem; color:white">15层</router-link> -->
            <div style="font-size:0.2rem; color:white" @click="toNext()"></div>
        </div>
    </div>
</template>

<script>
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader'
import Stats from 'stats.js/build/stats.min.js'

// 定义three全局变量
const scene = new THREE.Scene;
// three的控制器必须放在data外，否则会造成卡顿
let controls;
// 帧率显示插件
let stats;

export default {
    data() {
        return {
            camera: null,
            renderer: null,
            mesh: null,
            stats: null,
            floorPosition: null,
            loading: true,
        };
    },
    mounted() {
        this.init();
        this.animate();
        // this.addModels();
        this.cancelLoading();
    },
    methods: {
        // 加载中loading...动画
        cancelLoading() {
            setTimeout(() => {
                this.loading = false
            }, 500)
        },
        // 初始化
        init() {
            // 创建场景对象Scene
            this.scene = new THREE.Scene()
            // 相机设置
            let container = this.$refs.container
            this.camera = new THREE.PerspectiveCamera(
                70,
                container.clientWidth / container.clientHeight,
                0.01,
                1000
            );
            this.camera.position.set(55,45,65)
            // 光线
            this.scene.add(new THREE.AmbientLight(0xffffff));
            // 创建渲染器对象
            this.renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true, powerPreference: "high-performance" });
            this.renderer.setSize(container.clientWidth, container.clientHeight);
            container.appendChild(this.renderer.domElement);
            // 创建控件对象
            this.controls = new OrbitControls(this.camera, this.renderer.domElement);
            // this.controls.addEventListener('change', this.animate());
            // 坐标轴辅助工具
            let helper = new THREE.AxesHelper(50)
            this.scene.add(helper)
            // 显示帧率
            this.stats = new Stats()
            container.appendChild(this.stats.dom)
            // 启用浏览器调试插件Three.js inspector
            window.scene = this.scene;
            window.THREE = THREE;
        },
        // 动画
        animate() {
            this.stats.update();
            requestAnimationFrame(this.animate);
            this.renderer.render(this.scene, this.camera);  
        },
        // 导入模型
        addModels() {
            // 加载1、2、3层形状不一样的楼层
            let loader1 = new GLTFLoader()
            loader1.load('models/Three/single_floor/1F.gltf',obj => {
                obj.scene.position.y = -20;
                this.scene.add(obj.scene)       
            },xhr => {
                console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
            }) 
            let loader2 = new GLTFLoader()
            loader2.load('models/Three/single_floor/2F.gltf',obj => {
                obj.scene.position.y = -21.6;
                this.scene.add(obj.scene)
            })
            let loader3 = new GLTFLoader()
            loader3.load('models/Three/single_floor/3F.gltf',obj => {
                obj.scene.position.y = -23;
                this.scene.add(obj.scene)
            })
            // 加载形状完全相同的楼层 4~18层
            let loader4 = new GLTFLoader()
            loader4.load('models/Three/single_floor/15F.gltf',obj => {
                obj.scene.position.y = -73;
                obj.scene.children[0].children[4].visible = false
                obj.scene.children[0].children[107].visible = false
                for(let i = 0; i < 33; i++){
                    obj.scene.children[0].children[6+i].visible = false
                }
                this.scene.add(obj.scene)
            })
        },
        // 复制完全相同的楼层，构建出4~18层的模型
        copyModels() {
            let Object3D = new THREE.Object3D()
            Object3D = this.scene.children[5].clone()
            Object3D.position.y = 10
            this.scene.add(Object3D)
        },
        // 跟随窗口大小变动
        onWindowResize() {
            this.camera.aspect = window.innerWidth / window.innerHeight
            this.camera.updateProjectionMatrix()
            this.controls.handleResize()
        },
        // 楼层标签显示位置卡顿
        getFloorLabel() {
            // 获得15层天花板的坐标
            let worldVector = new THREE.Vector3()
            this.scene.children[2].children[19739].getWorldPosition(worldVector)
            // 世界坐标转标准设备坐标
            // standVector是WebGL设备坐标
            let standVector = worldVector.project(this.camera)
            // WebGL标准设备坐标转屏幕坐标
            const a = window.innerWidth / 2
            const b = window.innerHeight / 2 
            let x = Math.round(standVector.x * a + a)
            let y = Math.round(-standVector.y * b + b)
            let div = this.$refs.floorLabel
            div.style.left = x+250 + 'px'
            div.style.top = y + 'px'
        },
        // 清空当前页面占用的浏览器显存，避免路由切换之后造成卡顿
        clearCache() {
            this.renderer.dispose();
            this.renderer.forceContextLoss();
            this.renderer.context = null;
            this.renderer.domElement = null;
            this.renderer = null;
        },
        // 前往具体楼层页面
        toNext() {
            this.$router.push('/Floor_15')
            this.clearCache()
        },
        // 创建出博士后产业园的楼宇模型
        async addBuilding() {
            await this.addModels()
        }
     } 
}
</script>

<style lang="less" scoped>
#container {
  position: absolute;
  width: 100%;
  height: 100%;
  background-image: url("../assets/images/background.png");
  background-size: cover;
  z-index: -1;
}    
.floor-labels{
    width: 2rem;
    height: 0.4rem;
    position: absolute;
    z-index: 1;
    border: 1px solid greenyellow;
  }
</style>